package wsi.gui.predpath;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.JFileChooser;

import org.rygh.core.util.UIo;
import org.rygh.gui.swing.presenter.SwingPresenter;
import org.rygh.gui.swing.table.STableView;
import org.rygh.semantic.func.RdfPathFunctionality;
import org.rygh.semantic.func.RdfPathFunctionalityParser;

public class PredicatePathPresenter extends SwingPresenter {

	public interface Display extends SwingPresenter.Display {
		STableView getTable();
	}

	private final PredicatePathTableModel tableModel = new PredicatePathTableModel();
	private final RdfPathFunctionalityParser parser = new RdfPathFunctionalityParser();
	private final Map<String, RdfPathFunctionality> functionalityMap = new HashMap<>();
	private final JFileChooser fileChooser = new JFileChooser();

	public PredicatePathPresenter() {
		display = new PredicatePathWindow(this);

		bind();
	}

	@Override
	public void bind() {
		super.bind();

		Display d = (Display) display;
		d.getTable().setModel(tableModel);
	}

	public void clear() {
		functionalityMap.clear();
		tableModel.clear();
		tableModel.fireTableDataChanged();
	}

	public void merge() {
		int ret = fileChooser.showOpenDialog(getWindow());

		if (ret == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();

			parser.parse(UIo.readFile(file));
			merge(parser.getFunctionalityMap());
		}
	}

	private void merge(Map<String, RdfPathFunctionality> map) {
		RdfPathFunctionality val1, val2;
		boolean ok = true;

		for (String key : map.keySet()) {
			if (!functionalityMap.containsKey(key))
				continue;

			val1 = functionalityMap.get(key);
			val2 = map.get(key);

			if (!val1.equalsTo(val2)) {
				getWindow()
						.message(
								String.format(
										"The following values are discrepant for %s.\n%s vs. %s",
										key, val1.toMessage(), val2.toMessage()));
				ok = false;
				break;
			}
		}

		if (!ok)
			return;

		int id = tableModel.getRowCount() + 1;
		int count = tableModel.getRowCount();

		for (Entry<String, RdfPathFunctionality> f : map.entrySet()) {
			if (functionalityMap.containsKey(f.getKey()))
				continue;

			functionalityMap.put(f.getKey(), f.getValue());
			tableModel.add(new PredicatePathTuple(id++, f.getValue()));
		}

		tableModel.fireTableDataChanged();

		getWindow().message(
				String.format("Merged %d tuples.", tableModel.getRowCount()
						- count));
	}

	public void save() {
		int ret = fileChooser.showSaveDialog(getWindow());

		if (ret == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();

			StringBuilder sbuilder = new StringBuilder();

			for (RdfPathFunctionality i : functionalityMap.values()) {
				if (i.getValue().isTemp())
					continue;

				sbuilder.append(i.toMachineString());
				sbuilder.append("\r\n");
				sbuilder.append(i.toInverseMachineString());
				sbuilder.append("\r\n");
			}

			UIo.saveFile(file, sbuilder.toString());
		}
	}
}
